package com.llh.cheap;

import com.llh.cheap.configs.*;
import com.qxt.stars.FileConverter;
import com.qxt.stars.models.HWSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.*;
import org.springframework.format.FormatterRegistry;
import org.springframework.http.converter.ByteArrayHttpMessageConverter;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.GsonHttpMessageConverter;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.multipart.support.StandardServletMultipartResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import top.moirae.core.Money;
import top.moirae.json.converter.AbstractOptionConverter;
import top.moirae.json.converter.LocalDateConverter;
import top.moirae.json.converter.LocalDateTimeConverter;
import top.moirae.json.converter.LocalTimeConverter;
import top.moirae.json.gson.Json;
import top.moirae.json.gson.serializers.LocalDateSerializer;
import top.moirae.json.gson.serializers.LocalDateTimeSerializer;
import top.moirae.json.gson.serializers.LocalTimeSerializer;
import top.moirae.json.gson.serializers.MoneySerializer;
import top.moirae.security.SecurityInterceptor;
import top.moirae.security.SessionResolver;
import top.moirae.security.services.SessionService;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List;

@Configuration
@EnableWebMvc
@Import({
        BusinessConfig.class,
        BusinessDBConfig.class,
        SecurityConfig.class,
        DepartmentConfig.class,
        RedisConfig.class,
        SmsConfig.class,
        SSOConfig.class,
        FileConfig.class,
        StarsConfig.class,
})
@PropertySource("classpath:app.properties")
@EnableScheduling
@EnableAspectJAutoProxy
public class WebConfig implements WebMvcConfigurer {
    private static final Logger LOGGER = LoggerFactory.getLogger(WebConfig.class);
    private final SessionService sessionService;
    private final String xrwWhite;

    @Autowired
    public WebConfig(SessionService sessionService, @Value("${request.valid.white_list}") String xrwWhite) {
        this.sessionService = sessionService;
        this.xrwWhite = xrwWhite;
    }

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        Json.addTypeAdapter(LocalDateTime.class, new LocalDateTimeSerializer("yyyy-MM-dd HH:mm:ss"));
        Json.addTypeAdapter(LocalDate.class, new LocalDateSerializer());
        Json.addTypeAdapter(LocalTime.class, new LocalTimeSerializer());
        Json.addTypeAdapter(Money.class, new MoneySerializer());
        Json.addTypeAdapter(HWSource.class, new FileConverter());
        converters.add(new GsonHttpMessageConverter(Json.BUILDER.create()));
        converters.add(new ByteArrayHttpMessageConverter());
        converters.add(new StringHttpMessageConverter());
    }

    @Bean
    public StandardServletMultipartResolver multipartResolver() {
        return new StandardServletMultipartResolver();
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new SecurityInterceptor(xrwWhite, sessionService));
    }

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
        resolvers.add(new SessionResolver());
    }

    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addConverter(new LocalDateTimeConverter());
        registry.addConverter(new LocalTimeConverter());
        registry.addConverter(new LocalDateConverter());
        registry.addConverter(new AbstractOptionConverter());
        WebMvcConfigurer.super.addFormatters(registry);
    }

}
